package com.zhuj.client.proxy;

import com.zhuj.client.NrpcClient;
import com.zhuj.core.Global;
import com.zhuj.core.entity.ClientRequest;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Administrator on 2018/1/3.
 */
public class NrpcInvocationHandler implements InvocationHandler {

    private Lock lock = new ReentrantLock();

    private Map<Integer,Object> result;

    private Class target;

    public NrpcInvocationHandler(Class target){
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        ClientRequest request = new ClientRequest();
        Integer requestId = Global.getRequest_id();
        request.setRequestId(requestId);
        request.setService(target.getSimpleName());
        request.setMethod(method.getName());
        request.setParamTypes(method.getParameterTypes());
        request.setParams(args);
        Condition condition = lock.newCondition();
        NrpcClient.processRunnable.putInvocation(requestId,new Object[]{this,condition});
        NrpcClient.sendRequest(request);
        await(condition);
        Object result = this.result.get(request.getRequestId());
        this.result.remove(requestId);
        return result;
    }

    public void await(Condition condition){
        lock.lock();
        try {
            condition.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void signal(Condition condition){
        lock.lock();
        condition.signal();
        lock.unlock();
    }

    public void setResult(Integer id,Object result) {
        this.result.put(id,result);
    }
}
